/*
 * measure.c
 *
 * Created: 2012-07-26 08:45:55
 *  Author: Antrykot
 */ 



#include "sc-p-ps.h"
#include "measure.h"

u8 adc_chan = 0;
u16 adc_readout = 0;

u16 x_aku = STD_AKU_MINUS;
u16 x_pow = STD_AKU_MINUS;

u16 v_aku;
u16 v_pow;
u16 v_dc;
u16 v_temp;

u16 v_pres = 0;
u16 v_rh = 0;
 

void calc_pa()
{
	adc_chan = 0;
	adc_read();
	 
	float ap = adc_readout * ap_a - ap_b;
	
	if (adc_readout > 3950)
	{
		v_pres = 25000;
		return;
	}
	if (adc_readout < 100)
	{
		v_pres = 10;
		return;
	}
	
	if (ap > 25000)
	{
		v_pres = 25001;		// 
		return;
	}
	if (ap < 100)
	{
		v_pres = 100;
		return;
	}
	
	v_pres = ap  ;
}

#define SHT_WAIT	WAITUS(200);
#define SHT_WAITL	WAITUS(300);

void calc_pd()
{
	adc_chan = 0;
	adc_read();
	
	float pd = adc_readout * ap_a - ap_b ;
/*
	if (pd < - 40)		// out of range
	{
		v_pres = 0x3FFF;
		return;
	}
*/
	if (adc_readout > 4000 || adc_readout < 10)					// out of range of adc (4095)
	{
		v_pres = 0x3FFE;
		return;
	}
	
	if (pd < 0)
	{
		v_pres = - pd;
		v_pres |= (1 << 12);		/// minus
	}
	
	v_pres = pd  ;
}

void rh_clk()
{
	RH_SCK_H;
	SHT_WAIT;
	RH_SCK_L;
	SHT_WAIT;
}

void rh_byte(u8 byte)
{
	for (i8 c = 7; c >= 0; c--)
	{
		if (byte & (1 << c))
		{
			RH_DTA_H;
		}			
		else
		{
			RH_DTA_L;
		}			
		rh_clk();
	}
	RH_DTA_L;
	RH_SCK_H;
	SHT_WAIT;
	RH_SCK_L;	//ACK
}

u8 rh_getbyte()
{
	u8 byte = 0;
	for ( i8 c = 7; c >= 0; c--)
	{
		RH_SCK_H;
		if (RH_DATA)
		{
			byte |= 1 << c; 
		}
		WAITUS(50);
		RH_SCK_L;
		WAITUS(50);
	}		
	return byte;
}

void reset_sht()
{
	
}

void ask_sht(u8 val)
{
	RH_SCK_L;
	RH_DTA_H;
	WAITUS(400);
	
	for (u8 c = 0; c < 10; c++)		// reset seq
	{
		RH_SCK_H;
		SHT_WAIT;
		RH_SCK_L;
		SHT_WAIT;
	}
	
	WAITUS(400);
	
	RH_SCK_H;
	SHT_WAITL;
	RH_DTA_L;
	SHT_WAITL;
	RH_SCK_L;
	SHT_WAITL;
	RH_SCK_H;
	SHT_WAITL;
	RH_DTA_H;
	SHT_WAITL;
	RH_SCK_L;
	SHT_WAITL;
	RH_DTA_L;
	SHT_WAITL;
	SHT_WAITL; 
	/// ~ preambul
	
	rh_byte(val);			// humid
	
	RH_DTA_H;
}

void calc_rh()
{
	static u8 r_err = 0;
	
	ask_sht(0x05);		// humidity
	u16 c = 0;
	while (1)
	{
		c++;
		WAITUS(100);
		if (c > 8000 )
		{
			r_err ++;
			if (r_err > 35)
			{
				v_rh = 0x3FFF;
				r_err = 35;
			}			
			return;
		}			
		if ((!RH_DATA))
			break;
	}
	
	r_err = 0;
	u16 humid = rh_getbyte();
	humid = humid << 8;
	RH_DTA_L;
	RH_SCK_H;
	WAITUS(70);
	RH_SCK_L;
	WAITUS(10);
	RH_DTA_H;
	humid |= rh_getbyte();
	
	double hum = -2.0468 + (0.0367 * humid);
	hum -= 0.0000015955 * (humid * humid);
	
	if (hum < 1 || hum > 99.9)
	{
		hum = 101;
		r_err++;
		if (r_err > 35)
		{
			r_err = 35;
		}
		else
		{
			return;
		}
	}		
	
	v_rh = hum  * 10;
}	
	
void calc_t()
{
	ask_sht(0x03);		// temp
	
	
	static u8 t_err = 0;
	u16 c = 0;
	while (1)
	{
		c++;
		WAITUS(100);
		if (c > 8000 )
		{
			t_err ++;
			if (t_err > 40)
			{
				v_temp = 0x3FFF;
				v_temp = -12 * 10 + 200;
				t_err = 40;
			}
			return;
		}
		if ((!RH_DATA))
		break;
	}	
	i16 temp = rh_getbyte();
	temp = temp << 8;
	RH_DTA_L;
	RH_SCK_H;
	WAITUS(70);
	RH_SCK_L;
	WAITUS(10);
	RH_DTA_H;
	temp |= rh_getbyte();
	
	double T = -39.6 + (0.01 * temp);
	
	if (T < -20)
	{
		T = -20.1;
		t_err++;
	}		
	else if (T > 49.9)
	{
		T = 50.1;
		t_err++;
	}		
	else
	{
		t_err = 0;
	}
	v_temp = T  * 10 + 200;

}


void calc_aku()
{
	u16 result = 0;
	adc_chan = 1;
	for (u8 c = 0; c < 10; c++)
	{
		adc_read();
		result += adc_readout;
		WAITMS(1);
	}
	result /= 10;
	float aku = result * 6.10;
	aku += x_aku - STD_AKU_MINUS;
	v_aku = aku;
}

void calc_pow()
{
	u16 result = 0;
	adc_chan = 3;
	for (u8 c = 0; c < 10; c++)
	{
		adc_read();
		result += adc_readout;
		WAITMS(1);
	}
	result /= 10;
	float pow = result * 6.10;
	pow += x_pow - STD_AKU_MINUS;
	v_pow = pow;
}

void calc_dc()
{
	adc_chan = 2;
	adc_read();
	float dc = adc_readout * 6.10;
	v_dc = dc;
}

void adc_read()
{
	cli();
	
	DIN_HIG;
	WAITUS(20);
	CS_LOW;
	WAITUS(20);
	adc_clk();
	DIN_HIG;		// single ended
	adc_clk();
	DIN_LOW;		// D2
	adc_clk();
	if (adc_chan & 0x02)
	{
		DIN_HIG;
	}		
	else
	{
		DIN_LOW;
	}		
	adc_clk();
	if (adc_chan & 0x01)
	{
		DIN_HIG;
	}		
	else
	{
		DIN_LOW;
	}		
	adc_clk(); // D0
	DIN_HIG;
	adc_clk(); // empty
	adc_clk(); // empty
	adc_clk(); // empty
	
	adc_readout = 0;
	for (i8 c = 11; c >= 0; c--)
	{
		CLK_HIG;
		WAITUS(20);
		CLK_LOW;
		//WAITUS(5);
		adc_readout |= ( ( DOUT ) << c);
	}		
		
	CS_HIG;
	DIN_HIG;
	CLK_HIG;
	sei();
}

inline void adc_readbit(u8 offset)
{
	CLK_HIG;
	WAITUS(10);
	CLK_LOW;
	WAITUS(10);
	adc_readout |= ( ( DOUT ) << offset);
}

void adc_clk()
{
	CLK_LOW;
	WAITUS(20);
	CLK_HIG;
	WAITUS(20);
}

void ser_def_low()
{



		
}

void ser_def_high()
{




}
